// 付款申请单：报销单为蓝本，去除关联申请单，合同， 优化逻辑。
import React from 'react';
import moment from 'moment';
import isJSON from 'is-json';
import { connect } from 'react-redux';
import debounce from 'lodash.debounce';
import menuRoute from 'routes/menuRoute';
import Chooser from 'components/chooser';
import customField from 'share/customField';
import baseService from 'share/base.service';
import chooserData from 'share/chooserData';
import errorMessage from 'share/errorMessage';
import { Form, Button, message, Spin } from 'antd';
import { messages, deepFullCopy } from 'share/common';
import 'styles/expense-report/new-expense-report.scss';
import expenseReportService from 'containers/expense-report/expense-report.service';
import paymentService from 'containers/payment-request/payment-service';

const FormItem = Form.Item;
let newExpenseReportThis;
let firstInitLoad;

class NewExpenseReport extends React.Component {
  constructor(props) {
    super(props);
    newExpenseReportThis = this;
    firstInitLoad = false;
    this.state = {
      loading: true,
      submitting: false,
      signEnable: false,
      formDetail: {},
      formDefaultValue: [], //表单默认值
      approvalAddSignScope: [], //加签人列表
      expenseReport: deepFullCopy(props.params.expenseReport),
      isInitDefaultValue: true, //是否在初始化默认值，若为true，则不触发formItemChange方法，bug 32149
      jobInfo: props.params.jobInfo || {},
    };
    this.handleCostCenter = debounce(this.handleCostCenter, 300);
  }

  //处理代理单据逻辑
  dealProxies(usersOID) {
    baseService.changeLoginInfo(usersOID)
      .then(() => {
        this.init();
      })
      .catch(() => {
        location.href = '/';
        message.error(messages('common.error')/*哦呼，服务器出了点问题，请联系管理员或稍后再试:(*/);
      });
  };

  handleFormDetail = async () => {
    const { params: { formId, formDetail } } = this.props;
    if (formDetail) {
      await this.setState({ formDetail: formDetail });
    } else {
      const ret = await baseService.getFormDetail(formId);
      await this.setState({ formDetail: ret.data });
    }
  };

  componentDidMount() {
    const { user } = this.props;
    const { formId, userOID } = this.props.params;
    if (formId && userOID && userOID !== ':userOID' && userOID !== user.userOID) {
      this.dealProxies(userOID);
    } else {
      this.init();
    }
  }

  init() {
    this.setState({ loading: true });
    const { formId, formDetail, applicantJobId } = this.props.params;
    Promise.all([this.handleFormDetail(), this.getFormDefaultValue(), this.getJobInfo(), this.isCounterSignEnable(formId || formDetail.formOID, applicantJobId)])
      .finally(() => {
        this.setState({ loading: false });
        setTimeout(() => {
          this.setState({ isInitDefaultValue: false });
        }, 500);
      });
  }

  //获取表单默认值
  getFormDefaultValue = async (userOID = this.props.user.userOID) => {
    const { formId, applicantJobId } = this.props.params;
    const jobId = applicantJobId === ':applicantJobId' ? void 0 : applicantJobId;
    const ret = await expenseReportService.getFormValue(userOID, formId, jobId);
    await this.setState({ formDefaultValue: ret.data });
  };

  // 获取滚动元素相对元素对象
  getPopupContainer = () => {
    return this.refs.newExpenseReport;
  };

  //处理是否启用时间
  processEnableTime = (field) => {
    let enableTime = false;
    if (field.fieldConstraint && JSON.parse(field.fieldConstraint) && JSON.parse(field.fieldConstraint).enableTime) {
      enableTime = true;
    }
    return enableTime;
  };

  //处理启用时间默认值
  processDefaultTime = (field) => {
    let defaultTime = null;
    if (field.fieldConstraint && JSON.parse(field.fieldConstraint)) {
      if (JSON.parse(field.fieldConstraint).defaultTime) {
        defaultTime = moment(moment(JSON.parse(field.fieldConstraint).defaultTime)
          .format('HH:mm'), 'HH:mm');
      } else {
        if (field.messageKey === 'start_date') {
          defaultTime = moment('00:00', 'HH:mm');
        }
        if (field.messageKey === 'end_date') {
          defaultTime = moment('23:59', 'HH:mm');
        }
      }
    }
    return defaultTime;
  };

  //获取岗位详情
  getJobInfo = async () => {
    const { applicantJobId } = this.props.params;
    if (applicantJobId) {
      const ret = await expenseReportService.getJobInfo(applicantJobId);
      await this.setState({ jobInfo: ret.data || {} });
    }
  };

  renderFormItem = () => {
    const { getFieldDecorator, getFieldsValue } = this.props.form;
    const { applicantJobId } = this.props.params;
    let { formDetail, formDefaultValue, expenseReport, jobInfo } = this.state;
    const { companyOID, departmentOID } = jobInfo;
    const formItemLayout = {
      labelCol: { span: 6 },
      wrapperCol: { span: !expenseReport ? 10 : 14, offset: 1 },
    };
    let customFormFields = deepFullCopy(formDetail.customFormFields || []);
    const messageKeys = [
      ['input', { max: 50 }],
      ['title', { max: 500 }],
      ['text_area', { max: 1000 }],
      ['employee_expand', { max: 200 }],
      ['remark', {}],
      ['destination', {}]
    ];
    const map = new Map(messageKeys);
    const validator = (item, value, callback, name) => {
      if (value && !value.trim()) {
        callback(messages('common.name.is.required',{arg1: name})/*{arg1}必填*/);
      }
      callback();
    };
    if (expenseReport) {
      customFormFields = deepFullCopy(expenseReport.custFormValues || customFormFields);
      formDetail.customFormFields = customFormFields;
    }
    customFormFields.length > 0 && customFormFields.sort((a, b) => a.sequence > b.sequence || -1);
    return customFormFields
      .map(field => {
        if (field.messageKey === 'select_participant' && field.hide) {
          return;
        }
        let switchMessageKey = ['switch', 'writeoff_flag'];
        let option = {
          valuePropName: ~switchMessageKey.indexOf(field.messageKey) ? 'checked' : 'value',
          rules: []
        };
        let fieldNameHelp = '';
        //表单默认值
        let fieldDefaultValue = {};
        formDefaultValue.map(item => {
          item.fieldOID === field.fieldOID && (fieldDefaultValue = item);
        });
        if (expenseReport) {
          option.initialValue = customField.getInitialValue(field);
        } else {
          option.initialValue = customField.getDefaultValue(field, fieldDefaultValue);
        }
        //开始结束日期以组合组件range_picker显示
        if (field.messageKey === 'start_date') {
          //开始结束日期都有值时，该组件才有值
          let firstName = field.fieldName,
            endName = '',
            startValue = field.value;
          customFormFields.map(fieldItem => {
            if (fieldItem.messageKey === 'end_date') {
              endName = fieldItem.fieldName;
              startValue && fieldItem.value && (option.initialValue = [moment(field.value), moment(fieldItem.value)]);
            }
          });
          //开始结束日期都启用时间时，该组件才启用时间
          if (this.processEnableTime(field)) {
            field.defaultValueTime = [];
            field.defaultValueTime.push(this.processDefaultTime(field));
            customFormFields.map(fieldItem => {
              if (fieldItem.messageKey === 'end_date' && this.processEnableTime(fieldItem)) {
                field.defaultValueTime.push(this.processDefaultTime(fieldItem));
                field.enableTime = true;
              }
            });
          }
          field.messageKey = 'range_picker';
          field.fieldName = firstName + '-' + endName;
          field.promptInfoList = [firstName, endName];
        }
        if (field.required) {
          option.rules.push({
            required: field.required,
            message: messages('common.name.is.required',{arg1: field.fieldName})/*{arg1}必填*/  //${field.fieldName}必填
          });
          if (map.has(field.messageKey)) {
            option.rules.push(
              {
                validator: (item, value, callback) => validator(item, value, callback, field.fieldName)
              }
            );
          }
        }

        if (map.has(field.messageKey)) {
          if (field.messageKey === 'employee_expand') {
            if (!(field.fieldContent && (JSON.parse(field.fieldContent) || {}).messageKey === 'cust_list')) {
              option.rules.push(
                {
                  max: map.get(field.messageKey),
                  message: messages('common.max.characters.length',{arg1: map.get(field.messageKey).max})/*最多输入{arg1}个字符*/
                });
            }
          } else {
            map.get(field.messageKey).max &&
            option.rules.push(
              {
                max: map.get(field.messageKey).max,
                message: messages('common.max.characters.length',{arg1: map.get(field.messageKey).max})/*最多输入{arg1}个字符*/
              });
          }
        }
        //编辑模式不能修改申请人
        if (field.messageKey === 'applicant' && this.props.params.expenseReport) {
          field.isReadOnly = true;
        }
        if (field.messageKey === 'number') {
          if (field.fieldContent && JSON.parse(field.fieldContent)) {
            let fieldContentObject = JSON.parse(field.fieldContent);
            fieldNameHelp = fieldContentObject.unit ? `(${fieldContentObject.unit})` : '';
          }
        }
        let selectParticipantVisible = true;
        if (field.messageKey === 'select_participant' && field.fieldContent) {
          selectParticipantVisible = JSON.parse(field.fieldContent).isUse;
        }
        let label = `${field.fieldName}${fieldNameHelp}`;
        return (
          field.fieldOID &&
          field.messageKey !== 'ying_fu_select_approver' &&
          selectParticipantVisible &&
          field.messageKey !== 'end_date' &&
          !field.hide
        ) && (
          <FormItem {...formItemLayout} label={label || ' '} key={field.fieldOID} colon={!!label}>
            {getFieldDecorator(field.fieldOID, option)(
              customField.renderForm({
                field,
                fieldDefaultValue,
                formDetail,
                copyValue: null,
                formValues: getFieldsValue(),
                type: 2,
                getPopupContainer: this.getPopupContainer,
                propsParams: { companyOID, departmentOID },
                jobId: applicantJobId,
                jobInfo,
                form: this.props.form
              })
            )}
          </FormItem>
        );
      });
  };

  //切换了公司.或者切换部门都要查询是否要清空成本中心。
  handleCostCenter = async ({ selectDepartment, selectCompany }) => {
    let { params: { expenseReport, userOID }, form: { getFieldValue, setFieldsValue } } = this.props;
    let { formDetail: { customFormFields }, jobInfo: { companyOID, departmentOID } } = this.state;

    if (expenseReport) {
      customFormFields = expenseReport.custFormValues;
      userOID = expenseReport.applicantOID;
    }

    const params = {
      userOID,
      departmentOID,
      companyOID,
      costCenterItemOIDs: []
    };

    customFormFields.forEach(i => {
      if (i.messageKey === 'select_cost_center' && !i.isReadOnly) {
        let preCostCenter = getFieldValue(i.fieldOID);
        if (Object.prototype.toString.call(preCostCenter) === '[object Array]') {
          preCostCenter = preCostCenter.costCenterItemOID;
        }
        preCostCenter && params.costCenterItemOIDs.push(preCostCenter);
      }

      if (i.messageKey === 'select_company') {
        let preCompany = getFieldValue(i.fieldOID);
        if (Object.prototype.toString.call(preCompany) === '[object Object]') {
          preCompany = preCompany.key;
        }
        params.companyOID = selectCompany || preCompany || companyOID;
      }

      if (i.messageKey === 'select_department') {
        params.departmentOID = selectDepartment || getFieldValue(i.fieldOID) || departmentOID;
      }
    });

    if (!params.costCenterItemOIDs[0]) {
      return;
    }
    this.setState({ loading: true });
    try {
      const ret = await baseService.checkCostCenterNeedEmpty(params);
      customFormFields.forEach(i => {
        if (i.messageKey === 'select_cost_center' && !i.isReadOnly && !!getFieldValue(i.fieldOID) && !ret.data[getFieldValue(i.fieldOID)]) {
          setFieldsValue({ [i.fieldOID]: '' });
        }
      });
    }
    catch (e) {
      e && e.response ? errorMessage(e.response) : '';
    }
    this.setState({ loading: false });
  };

  //控件之间联动关系
  formItemChange = (value) => {
    const { enableDepCompany } = this.props;
    let { formDetail, isInitDefaultValue } = this.state;
    if (isInitDefaultValue) return;
    let customFormFields = formDetail.customFormFields || [];
    if (!(value && Object.prototype.toString.call(value) === '[object Object]')) return;
    customFormFields.map(item => {
      if (item.fieldOID in value) {
        if (item.messageKey === 'select_department') {
          this.handleCostCenter({ selectDepartment: value[item.fieldOID] });
        }
        //参与人部门权限控件
        if ((item.messageKey === 'select_department' || item.messageKey === 'select_cost_center')) {
          item.value = value[item.fieldOID];
          customFormFields.map(i => {
            if (i.messageKey === 'select_participant') {
              setTimeout(() => {
                firstInitLoad = true;
              }, 200);
              if (firstInitLoad) {
                i.clearDefault = true;
              }
              let fieldContent = i.fieldContent ? JSON.parse(i.fieldContent) : { editable: true };
              if (!i.isReadOnly && fieldContent.editable) {
                this.props.form.resetFields(i.fieldOID);
              }
            }
          });
        }
        //选择公司
        if (item.messageKey === 'select_company') {
          this.handleCostCenter({ selectCompany: value[item.fieldOID] });
          customFormFields.map(i => {
            if (i.messageKey === 'select_department' && !i.isReadOnly && enableDepCompany === 'OPEN') {
              this.props.form.setFieldsValue({ [i.fieldOID]: undefined });
            }
          });
          // 清空收款单位
          const venMaster = customFormFields.filter(item => {
            return item.messageKey === 'venMaster';
          })[0];
          if (venMaster) {
            this.props.form.setFieldsValue({ [venMaster.fieldOID]: undefined });
          }
        }
        //收款人银行关联控件
        if (item.messageKey === 'payee' && value[item.fieldOID] && typeof value[item.fieldOID] === 'object') {
          item.value = value[item.fieldOID]['key'];
          customFormFields.map(i => {
            if (i.messageKey === 'contact_bank_account') {
              let param = {
                userOID: value[item.fieldOID]['key'],
                page: 0,
                size: 20
              };
              let bank = { [i.fieldOID]: undefined };
              baseService.getUserBanks(param)
                .then(res => {
                  let data = res.data;
                  if (data && data.length > 0) {
                    data.map(item => {
                      if (item.isPrimary) {
                        bank = {
                          [i.fieldOID]: [{
                            bankAccountNo: item.bankAccountNo,
                            originalBankAccountNo: item.originalBankAccountNo,
                            contactBankAccountOID: item.contactBankAccountOID
                          }]
                        };
                      }
                    });
                  }
                  this.props.form.setFieldsValue(bank);
                })
                .catch(e => {
                  this.props.form.setFieldsValue(bank);
                });
            }
          });
        }
        if (item.messageKey === 'select_cost_center') {
          if (item.dataSource && JSON.parse(item.dataSource || '{}').type === 'father') { //父成本中心
            customFormFields.map(i => {
              //父成本中心修改时，子成本中心置空
              if (i.messageKey === 'select_cost_center' && i.dataSource && JSON.parse(i.dataSource || '{}').type === 'son') {
                this.props.form.setFieldsValue({ [i.fieldOID]: undefined });
              }
            });
          }
        }
      }
    });
  };

  //提交前检查组合控件的表单值验证,异步方法
  submitSaveValidateCombinationForm = () => {
    let { formDetail } = this.state;
    let customFormFields = formDetail.customFormFields || [];
    let isHaveValidate = false;
    let needValidateForms = ['venMasterSwitch', 'linkage_switch'];
    customFormFields.map(item => {
      if (~needValidateForms.indexOf(item.messageKey)) {
        let info = this.props.form.getFieldValue(item.fieldOID);
        if (info) {
          info.callBackSubmit = !info.callBackSubmit;
          this.props.form.setFieldsValue({ [item.fieldOID]: info });
          isHaveValidate = true;
        }
      }
    });
    return isHaveValidate;
  };

  //组合表单验证结果
  combinationFormValidateResult = () => {
    let { formDetail } = this.state;
    let customFormFields = formDetail.customFormFields || [];
    let isPassValid = true;
    let needValidateForms = ['venMasterSwitch', 'linkage_switch'];
    customFormFields.map(item => {
      if (~needValidateForms.indexOf(item.messageKey)) {
        let info = this.props.form.getFieldValue(item.fieldOID);
        if (info) {
          isPassValid = isPassValid && info.isPassValid;
        }
      }
    });
    return isPassValid;
  };

  handleSave = (e) => {
    e.preventDefault();
    if (this.submitSaveValidateCombinationForm()) {
      //组合子表单验证信息传递需要时间
      setTimeout(this.delayHandleSave, 10);
    } else {
      this.delayHandleSave();
    }
  };

  /**
   * 格式化时间为UTC格式(YYYY-MM-DDTHH:mm:ssZ)
   * @param date: string(YYYY-MM-DD HH:mm:ss)
   * @returns {string}
   */
  formatDateToUtc = (date) => {
    return moment(date)
      .utc()
      .format('YYYY-MM-DDTHH:mm:ss') + 'Z';
  };

  delayHandleSave = () => {
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (!this.combinationFormValidateResult()) {
        return;
      }
      const { applicantJobId } = this.props.params;
      let { formDetail, expenseReport } = this.state;
      let target = JSON.parse(JSON.stringify(expenseReport || formDetail));
      target.currencySame = this.checkFunctionProfiles('web.invoice.keep.consistent.with.expense', [true]);
      applicantJobId && applicantJobId !== ':applicantJobId' && (target.applicantJobId = applicantJobId);
      let customFormFields = deepFullCopy(formDetail.customFormFields || []);
      if (expenseReport) {
        customFormFields = deepFullCopy(expenseReport.custFormValues || []);
      } else {
        target.remark = null;
      }
      if (!err) {
        const { formId, userOID } = this.props.params;
        let custFormValues = [];
        let canSubmit = true;
        Object.keys(values)
          .map(key => {
            customFormFields
              .map(field => {
                if (key === field.fieldOID) {
                  custFormValues.push(customField.formatFormValue(field, values[key]));
                }
              });
          });
        target.countersignApproverOIDs = this.props.form.getFieldsValue().addSign;
        target.custFormValues = custFormValues;
        if (formId && userOID && userOID !== ':userOID') {
          target.applicantOID = userOID;
        }

        //fixed 45097
        //成本中心24的值 没有走以下这个遍历  原因是遍历的时候更改了原数组
        target.custFormValues.map((item, index) => {
          if (item.messageKey === 'select_cost_center') {
            try {
              item.value = isJSON(item.value) ? JSON.parse(item.value)[0].costCenterItemOID : (typeof item.value === 'string' ? item.value : item.value[0].costCenterItemOID);
            }
            catch (e) {
            }
          }
          // 计算公式额外校验
          if (item.messageKey === 'calculate_formula' && item.value && item.value.split('.')[0].length >= 16) {
            message.error(messages('expense-18.key51',{arg1: item.fieldName})/*{arg1}最多支持15位数字*/);
            canSubmit = false;
          }
        });
        target.custFormValues.map((item, index) => {
          //保存前要将连选日期控件range_picker分为开始日期／结束日期控件
          if (item.messageKey === 'start_date') {
            customFormFields.map(fieldItem => {
              if (fieldItem.messageKey === 'end_date') {
                let endDateItem = fieldItem;
                if (item.value) {
                  let rangePickerValue = deepFullCopy(item.value);
                  if (this.processEnableTime(item) && this.processEnableTime(fieldItem)) {
                    item.value = this.formatDateToUtc(rangePickerValue[0]);
                    endDateItem.value = this.formatDateToUtc(rangePickerValue[1]);
                  } else {
                    item.value = this.formatDateToUtc(moment(rangePickerValue[0])
                      .format('YYYY-MM-DD 00:00:00'));
                    endDateItem.value = this.formatDateToUtc(moment(rangePickerValue[1])
                      .format('YYYY-MM-DD 23:59:59'));
                  }
                }
                if (!item.value) {
                  item.value = undefined;
                  endDateItem.value = undefined;
                }
                target.custFormValues.splice(index + 1, 0, endDateItem);
              }
            });
          }
        });
        if (!canSubmit) return;
        !expenseReport && (target.recalculateSubsidy = true);
        this.setState({ submitting: true });
        paymentService.newPaymentRequest(target)
          .then(res => {
            this.setState({ submitting: false });
            message.success(res.data.draftToast || messages('common.save.success',{arg1: ''})/*{arg1} 保存成功*/);
            if (expenseReport) {
              this.props.close({ refresh: true, refreshAccount: !!res.data.draftToast });
            } else {
              let url = (
                menuRoute.getRouteItem('payment-details')
                  .url
                  .replace(':paymentRequestOID', res.data)
              );
              this.context.router.push(url);
            }
          })
          .catch(error => {
            this.setState({ submitting: false });
          });
      }
    });
  };

  //是否可以审批加签
  isCounterSignEnable = async (formOID) => {
    const ret = await expenseReportService.isCounterSignEnable(this.props.company.companyOID, formOID, 'enableAddSignForSubmitter');
    await this.setState({
      signEnable: ret.data.enabled,
      approvalAddSignScope: ret.data.approvalAddSignScope.companyOIDs
    });
  };

  //返回
  goBack = () => {
    const { close } = this.props;
    close ? close() : window.history.go(-1);
  };

  render() {
    const { loading, formDetail, submitting, signEnable, approvalAddSignScope, expenseReport } = this.state;
    const { getFieldDecorator } = this.props.form;
    const formItemLayout = {
      labelCol: { span: 6 },
      wrapperCol: { span: !expenseReport ? 10 : 14, offset: 1 },
    };
    let signPerson = [];
    expenseReport && expenseReport.countersignApproverNames && expenseReport.countersignApproverNames.map(item => {
      signPerson.push({ userOID: item.userOID, fullName: item.fullName });
    });
    let companyDTOS = approvalAddSignScope.length ? approvalAddSignScope : null;
    let signName = customField.getSignNameForSubmitter(formDetail && formDetail.customFormPropertyMap);
    return (
      <div className="new-expense-report" ref='newExpenseReport'>
        {!expenseReport && <div className="form-name">{formDetail.formName}</div>}
        <Form onSubmit={this.handleSave}>
          <FormItem {...formItemLayout} label=" " colon={false}>
            {customField.instructionsTag(formDetail.customFormPropertyMap)}
          </FormItem>
          <Spin spinning={loading}>
            {this.renderFormItem()}
          </Spin>
          {signEnable && (
            <FormItem {...formItemLayout} label={signName} key="addSign">
              {getFieldDecorator('addSign', {
                rules: [{
                  required: formDetail.customFormPropertyMap && formDetail.customFormPropertyMap.enableCounterSignForSubmitterMustWriter === 'true',
                  message: messages('common.can.not.be.empty',{arg1: signName})/*{arg1} 不能为空*/
                }],
                initialValue: signPerson
              })(
                <Chooser
                  selectorItem={function () {
                    let chooserItemUser = deepFullCopy(chooserData['user']);
                    chooserItemUser.title = signName;
                    return chooserItemUser;
                  }(this)}
                  valueKey="userOID"
                  labelKey="fullName"
                  onlyNeed="userOID"
                  maxNum={26}
                  listExtraParams={{
                    corporationOID: companyDTOS,
                    roleType: 'TENANT',
                    companyOID: companyDTOS
                  }}
                  showArrow={formDetail.customFormPropertyMap && formDetail.customFormPropertyMap.countersignType === '2'}
                  newline/>
              )}
            </FormItem>
          )}
          <div className={expenseReport ? 'slide-footer' : 'buttons'}>
            <Button type="primary" htmlType="submit" loading={submitting} className="button-new">
              {expenseReport ? messages('common.save')/*保存*/ : messages('common.create')/*新建*/}
            </Button>
            <Button onClick={this.goBack}>{messages('common.cancel')/*取消*/}</Button>
          </div>
        </Form>
      </div>
    );
  }
}

NewExpenseReport.contextTypes = {
  router: React.PropTypes.object
};

function mapStateToProps(state) {
  return {
    user: state.login.user,
    language: state.main.language,
    company: state.login.company,
    tenant: state.login.tenant,
    enableDepCompany: state.setting.enableDepCompany,
    options: state.login.options,
  };
}

NewExpenseReport.propTypes = {
  expenseReport: React.PropTypes.object
};

const WrappedNewExpenseReport = Form.create({
  onValuesChange(props, values) {
    newExpenseReportThis.formItemChange(values);
  },
})(NewExpenseReport);

export default connect(mapStateToProps)(WrappedNewExpenseReport);
